﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using IDI.Studio.Application.Common;
using IDI.Studio.Core.Util;

namespace IDI.Studio.Application
{
    public class MenuBuilder
    {
        #region Private Fields
        private const string m_fileName = "ConfigFiles\\MenuSection.config";
        private const string m_rootPath = "forms";
        private const string m_name = "name";
        private const string m_text = "text";
        private const string m_type = "type";
        private const string m_inMid = "inMid";
        private const string m_reference = "ref";
        private Dictionary<string, Form> forms;
        private Form formMDI;
        #endregion

        public MenuBuilder(Form MDIParent)
        {
            forms = new Dictionary<string, Form>();
            formMDI = MDIParent;
        }

        public void Initialize(ToolStripStatusLabel toolStripStatusLabel, ToolStripMenuItem toolStripMenuItem)
        {
            toolStripStatusLabel.Text = string.Format("{0}", Assembly.GetExecutingAssembly().GetName().Version);

            var doc = XmlUtil.GetXmlDocument(m_fileName);

            if (doc == null) return;

            var menus = doc.SelectSingleNode(m_rootPath).ChildNodes.Cast<XmlElement>().ToList();

            BindToolStripItem(menus, toolStripMenuItem.DropDownItems);

            toolStripMenuItem.DropDownItems.Add(new ToolStripSeparator());

            var menuItemCloseAll = new ToolStripMenuItem { Text = "Close All" };
            menuItemCloseAll.Click += new EventHandler((sender, args) =>
            {
                if (forms.Count == 0) return;

                if (MessageBox.Show("Are you sure close all windows?", string.Empty, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
                {
                    foreach (Form childForm in formMDI.MdiChildren)
                        childForm.Close();
                    forms.Clear();
                }
            });

            toolStripMenuItem.DropDownItems.Add(menuItemCloseAll);
        }

        private void BindToolStripItem(List<XmlElement> menus, ToolStripItemCollection collection)
        {
            foreach (var menu in menus)
            {
                string name = menu.HasAttribute(m_name) ? menu.GetAttribute(m_name) : string.Empty;
                string type = menu.HasAttribute(m_type) ? menu.GetAttribute(m_type) : string.Empty;
                string text = menu.HasAttribute(m_text) ? menu.GetAttribute(m_text) : string.Empty;
                bool showInMid = menu.HasAttribute(m_inMid) ? Convert.ToBoolean(menu.GetAttribute(m_inMid)) : true;
                string reference = menu.HasAttribute(m_reference) ? menu.GetAttribute(m_reference) : string.Empty;

                switch (type)
                {
                    case Constants.Setting.MenuType.MenuItem:
                        if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(text))
                        {
                            var menuItem = new ToolStripMenuItem { Name = name, Text = text };

                            if (!string.IsNullOrEmpty(reference))
                            {
                                menuItem.Click += new EventHandler((sender, args) =>
                                {
                                    var formType = Type.GetType(reference);

                                    if (formType != null)
                                    {
                                        var form = (Form)Activator.CreateInstance(formType);
                                        ShowForm(sender, form, showInMid);
                                    }
                                    else
                                    {
                                        MessageBox.Show(string.Format("Can not init form type <{0}>.", reference));
                                    }
                                });
                            }

                            if (menu.HasChildNodes)
                                BindToolStripItem(menu.ChildNodes.Cast<XmlElement>().ToList(), menuItem.DropDownItems);

                            collection.Add(menuItem);
                        }
                        break;
                    case Constants.Setting.MenuType.Separator:
                        collection.Add(new ToolStripSeparator());
                        break;
                    default:
                        break;
                }
            }
        }

        private void ShowForm(object sender, Form form, bool showInMid)
        {
            var menuItem = sender as ToolStripMenuItem;

            if (forms.ContainsKey(menuItem.Name) && !forms[menuItem.Name].IsDisposed)
            {
                form = forms[menuItem.Name];

                if (form.WindowState == FormWindowState.Minimized)
                    form.WindowState = FormWindowState.Maximized;
            }
            else
            {
                form.ShowIcon = false;
                form.Text = menuItem.Text;

                if (showInMid)
                {
                    form.MdiParent = formMDI;
                    form.WindowState = FormWindowState.Maximized;
                }

                if (forms.ContainsKey(menuItem.Name))
                    forms[menuItem.Name] = form;
                else
                    forms.Add(menuItem.Name, form);
            }

            form.StartPosition = FormStartPosition.CenterScreen;
            form.Show();
        }
    }
}
